-module(world_svr).
-behaviour(gen_server).
-export([start_link/2, stop/1, init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).
-include("common.hrl").
-record(state, {key,lastontime=0}).

start_link(Key,Moudle) ->
	?debug("--------------Key,Moudle=~p",[{Key,Moudle}]),
	%process_flag(trap_exit, true),
	{ok, Pid} = gen_server:start_link({global, Key}, ?MODULE, [Key,Moudle], []),
	?debug("key=~p,Pid=~p",[Key,Pid]),
	{ok, Pid}.

stop(Key) ->
	gen_server:cast({global, Key}, stop).

init([Key,Moudle]) -> 
	put(world_moudle,Moudle),
	put(world_key,Key),
	Ret = do_init(),
	
	erlang:start_timer(1000, self(), {timercast}),
	Ret.


handle_call(Msg, _From, State) ->
%% 	?debug("handle_call:~p,~p",[Msg,State]),
	Reply = try 
		Moudle = get_moudle(),
		Moudle:do_call(Msg)
	catch 
		E:R -> ?log_error("world handle_call error E=~p,R=~p,stack=~p",[E,R,erlang:get_stacktrace()]),error
	end,
	{reply, Reply, State}.  

handle_cast(stop, State) ->
	{stop, normal, State}; 
handle_cast({check}, State) ->
	gen_server:cast({global, sm}, {checkok, atom_to_list(get_key())}),
	{noreply, State};
handle_cast(Msg, State) ->
%% 	?debug("handle_cast:~p,~p",[Msg,State]),
	try 
		Moudle = get_moudle(),
		Moudle:do_msg(Msg)
	catch 
		E:R -> ?log_error("world handle_cast error E=~p,R=~p,stack=~p",[E,R,erlang:get_stacktrace()])
	end,		   
	{noreply, State}.

handle_info({timeout, TimerRef, {xtimer_callback, CallBackInfo}}, State) ->
	try
		xtimer:on_timer(TimerRef, CallBackInfo)
	catch E:R ->?log_error("timeout error,data=~p,E=~p,R=~p,stack=~p",[CallBackInfo,E,R,erlang:get_stacktrace()])
	end,
	{noreply, State};
handle_info({timeout, _TimerRef, {timercast}}, State) ->
	try
		Now = util:longunixtime(),
		Moudle = get_moudle(),
		Last = Moudle:do_time(Now),
		case erlang:is_integer(Last) of
			?TRUE ->
				erlang:start_timer(Last, self(), {timercast});
			_ -> ?SKIP
		end
	catch 
		E:R -> ?log_error("world handle_info  error E=~p,R=~p,stack=~p",[E,R,erlang:get_stacktrace()])
	end,
	{noreply, State};	
handle_info(Info, State) ->
	try 
		Moudle = get_moudle(),
		Moudle:do_info(Info)
	catch 
		E:R -> ?log_error("world handle_info  error E=~p,R=~p,stack=~p",[E,R,erlang:get_stacktrace()])
	end,
	{noreply, State}.

terminate(_Reason, State) ->
	?log_error("Info:public server stoped!Reason=~p,State=~p", [_Reason, State]),
	try 
		Moudle = get_moudle(),
		Moudle:do_close()
	catch 
		E:R -> ?log_error("world terminate  error E=~p,R=~p",[E,R])
	end,	  
	ok.

code_change(_OldVsn, State, _Extra) ->
    {ok, State}.


get_key() -> get(world_key).
get_moudle() -> get(world_moudle).

do_init() ->
	Key = get_key(),
	Moudle = get_moudle(),
	Moudle:do_init(),
	{ok, #state{key=Key}}.